package com.scu.bank.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.scu.bank.core.exception.ServiceException;
import com.scu.bank.model.dao.OrgInfoDao;
import com.scu.bank.model.example.OrgInfoExample;
import com.scu.bank.model.pojo.OrgInfo;
import com.scu.bank.model.base.BaseServiceImpl;
import com.scu.bank.model.vo.TreeNode;
import com.scu.bank.service.OrgInfoService;
import com.scu.bank.util.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

/**
 * Created by pmeng on 2021/01/05.
 */
@Service
@Transactional
public class OrgInfoServiceImpl extends BaseServiceImpl<OrgInfo,OrgInfoDao> implements OrgInfoService {
    @Autowired
    private OrgInfoDao orgInfoDao;

    @Override
    public OrgInfoDao getDao() {
        return orgInfoDao;
    }

    @Override
    public PageInfo<OrgInfo> list(Integer page, Integer size) {
        PageHelper.startPage(page, size);
        OrgInfoExample example = new OrgInfoExample();
        example.createCriteria().andIsDelEqualTo(false);
        PageInfo pageInfo = new PageInfo(orgInfoDao.selectByExample(example));
        return pageInfo;
    }

    /**
     * orgId = -1 或者null为增加根节点，其余为增加子菜单
     * @param orgName
     * @param orgId
     */
    @Override
    public void addOrgInfo(String orgName, String orgId) {

        String maxOrgCode;

        if ("-1".equals(orgId) || StringUtils.isEmpty(orgId)){
            //新增到根节点，查询根节点最大ocde
            maxOrgCode = getMaxOrgCode("-1");
        }else {
            OrgInfo orgInfo = getById(orgId);
            if (orgInfo == null){
                throw new ServiceException("目标节点id不存在");
            }

            //得到当前节点的orgCode
            String orgCode = orgInfo.getOrgCode();
            //先查询有没有最大子节点
            maxOrgCode = getMaxOrgCode(orgCode);
            if (maxOrgCode == null){
                //如果没有就新增一个
                maxOrgCode = orgCode + "0000";
            }
        }

        if (StringUtils.isEmpty(maxOrgCode)){
            // 如果一条数据都没有，就默认从0开始编号
            maxOrgCode = "0";
        }
        String newCode = String.valueOf(Integer.parseInt(maxOrgCode) + 1);
        OrgInfo orgInfo = new OrgInfo();
        orgInfo.setOrgCode(newCode);
        orgInfo.setOrgName(orgName);
        orgInfo.setOrgType("1");

        save(orgInfo);
    }

    @Override
    public TreeNode getTreeByParent(String pId) {
        String orgCode;

        TreeNode treeNode = new TreeNode();
        treeNode.setId("-1");
        treeNode.setLabel("scu管理系统");
        treeNode.setChildren(new ArrayList<>());

        if (StringUtils.isEmpty(pId)){
            orgCode = "-1";
        }else {
            OrgInfo pNode = getById(pId);
            if (pNode == null){
                orgCode = "-1";
            }else {
                orgCode = pNode.getOrgCode();
            }
        }

        setChildTreeNode(treeNode,orgCode);

        return treeNode;
    }

    @Override
    public void updateRogInfo(String orgName, String orgId) {
        OrgInfo orgInfo = getById(orgId);
        orgInfo.setOrgName(orgName);
        save(orgInfo);
    }

    @Override
    public void delete(String id) {
        OrgInfo orgInfo = getById(id);
        if (orgInfo == null){
            throw new ServiceException("数据不存在!");
        }
        OrgInfoExample example = new OrgInfoExample();
        example.createCriteria()
                .andIsDelEqualTo(false)
                .andOrgCodeLike(orgInfo.getOrgCode()+"%");

        OrgInfo pm = new OrgInfo();
        pm.setIsDel(true);
        orgInfoDao.updateByExampleSelective(pm,example);
    }

    @Override
    public OrgInfo getByOrgCode(String orgCode) {
        OrgInfoExample example = new OrgInfoExample();
        example.createCriteria()
                .andIsDelEqualTo(false)
                .andOrgCodeEqualTo(orgCode);

        List<OrgInfo> orgInfos = orgInfoDao.selectByExample(example);
        return ListUtils.isEmpty(orgInfos) ? null : orgInfos.get(0);
    }

    public void setChildTreeNode(TreeNode treeNode,String orgCode){
        List<OrgInfo> orgInfos = getOrgByLabelCode(orgCode);
        List<TreeNode> treeNodes = castOrgToTree(orgInfos);

        treeNode.setChildren(treeNodes);
        for (int i=0;i<orgInfos.size();i++){
            setChildTreeNode(treeNode.getChildren().get(i),orgInfos.get(i).getOrgCode());
        }
    }

    private List<TreeNode> castOrgToTree(List<OrgInfo> orgInfos){
        List<TreeNode> treeNodes = new ArrayList<>();
        if (ListUtils.isEmpty(orgInfos)){
            return treeNodes;
        }
        orgInfos.forEach((orgInfo -> {
            TreeNode treeNode = new TreeNode();
            treeNode.setId(orgInfo.getId());
            treeNode.setLabel(orgInfo.getOrgName());
            treeNodes.add(treeNode);
        }));
        return treeNodes;
    }

    public List<OrgInfo> getOrgByLabelCode(String labelCode){
        OrgInfoExample example = new OrgInfoExample();
        OrgInfoExample.Criteria criteria = example.createCriteria()
                .andIsDelEqualTo(false);

        if ("-1".equals(labelCode) || StringUtils.isEmpty(labelCode)){
            criteria.andOrgCodeLike("_");
        }else {
            criteria.andOrgCodeLike(labelCode + "____");
        }
        example.setOrderByClause("org_code desc");
        List<OrgInfo> orgInfos = selectByExample(example);
        return orgInfos;
    }

    public String getMaxOrgCode(String labelCode){
        List<OrgInfo> orgInfos = getOrgByLabelCode(labelCode);
        return ListUtils.isEmpty(orgInfos) ? null : orgInfos.get(0).getOrgCode();
    }
}
